//
//  basictest.cpp
//  HelloWorld
//
//  Created by Kevin Tang on 11/12/14.
//  Copyright (c) 2014年 Kevin Tang. All rights reserved.
//
#include <stdio.h>
#include <iostream>
#include <map>
#include "Common.h"
#include "VirtualFun.h"
#include "learnstl.h"
#include "miscellaneous.h"
//==============dynamic_cast==============================
//用法：dynamic_cast < type-id > ( expression )
//说 明：该运算符把expression转换成type-id类型的对象。
//      Type-id必须是类的指针、类的引用或者void *；
//      如果type-id是类指针类型，那么expression也必须是一个指针，
//      如果type-id是一个引用，那么expression也必须是一个 引用。
//==============static_cast==============================
//用法：static_cast < type-id > ( expression )
//说明：该运算符把expression转换为type-id类型，但没有运行时类型检查来保证转换的安全性。
//来源：为什么需要static_cast强制转换？
//情况1：void指针->其他类型指针
//情况2：改变通常的标准转换
//情况3：避免出现可能多种转换的歧义(相对于dynamic_cast来说的)




/**
 * 注意，我们这里讲的是从基类指针，转换成子类指针,static_cast和dynamic_cast之间的区别
 * 如果是从子类指针，向基类指针转换,它们的功能都是一样的。基等效.都是安全的转型
 * 因为子类继承了基类的所有特性.
 */
static void func(Base *pb)
{
    //若pb 是一个基类对象指针，即是Base类的对象，那么pb经过static_cast转型后
    //pd1指向的是Base类的对象。由于它是Base类型的。所以我们用pd1来操作Derived对象的成员
    //m_szName时会出错，因为pd1不是派生类Derived的对象。它没有m_szName这个成员.
    //这种操作是不安全的。
    Derived *pd1 = static_cast<Derived*>(pb);
    if (pd1) {//不会为空
        
        std::cout<< pd1->m_szNme <<std::endl;
            pd1->output();
        //strcpy(pd1->m_szNme,"abcdefghi");//访问出错,因为pd1是指向Base对象的指针。
        //Base对象没有m_szName成员
    }
    
    //若pb 是一个基类对象指针，经过dynamic_cast转型后，为NULL指针。
    //因为dynamic_cast发现pb不是Derived的对象指针。这个我们就不能使用pd2
    //我们对pd2加上条件判别 if(pd2){} 这样就能达到安全使用的目的.
    //而上面的pd1就不能。因为它不为null.而我们以为其是一个Derived类型的指针，然后访问其成员
    //方法或成员，会出错.
    Derived *pd2 = dynamic_cast<Derived*>(pb);
    
    if(pd2){
        //strcpy(pd2->m_szNme,"abcdefghi");
    }
    
}


static void TestCrossCast()
{ //交叉转换
    Derived1 *pd1 = new Derived1();
    pd1->m_iNum = 100;

    //下面的静态转型不支持,因为static_cast不支持交叉转型
    //Derived2 *pd2 = static_cast<Derived2*>(pd1);
    
    //下面pd3为null.
    Derived2 *pd3 = dynamic_cast<Derived2*>(pd1);
    if(pd3){
        pd3->m_iNum = 500;
    }
}
static void Testcast()
{
    //不能输出所有打印
    Base *mbase = new Base();
    func(mbase);//基类到子类的转换
    
    //能正确输出
    Derived *mderived = new Derived();
    func(mderived);
   

    TestCrossCast();
    
}

/*
 *虚方法的调用
 */

static void PatternsTest()
{
    
    //基类指针，指向子类对象
  //  VirtualBase *p = new VirtualInherit();
 //   p->fun();//这里调用的是父类的方法，因为不是虚方法。
    /**********************************************************
     * 1:这个虚方法调用，会调用继承类的方法，因为继承类继承了基类的方法，
     * 2:如果子类没有继承基类的虚方法，则调用基类的虚方法
     **********************************************************/
  //  p->v_fun();//
    
    //父类有一个虚方法名字是v_fun,子类的v_fun 无论是否使用了virtual关键字，都是虚方法
    VirtualInherit * sp = new Subc();
    sp->v_fun();
    
}

struct TypeValue{
    uint32_t curvalue;
    uint32_t nextvalue;
    TypeValue (uint32_t value1=0,uint32_t value2=0):curvalue(value1),nextvalue(value2)
    {
    }
    TypeValue & operator = (const TypeValue & v)
    {
        this->curvalue = v.curvalue;
        this->nextvalue = v.nextvalue;
        return *this;
    }
};


void BasicTest()
{
    //如果有默认构造函数，则会调用默认构造函数,这是c++创建对象的一种方式
    //同理，如果这个类中有一个对象成员变量，且有默认构造函数，那么也会首先调用该成员变量的初始化方法
//    Animal animal;
    
//    PatternsTest();
//    Testcast();
//    test_list_vect();
    
//      test_miscells();
    
    
    std::map<uint32_t,TypeValue> value;
}

